package com.iot.ic.tcp.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class SendCustomTCPServer extends AbstractSendCustomServer {
	private static final Logger LOG = LoggerFactory.getLogger(SendCustomTCPServer.class);

	private ServerBootstrap serverBootstrap;

	@PostConstruct
	@Override
	public void startServer() throws Exception {
		try {
			serverBootstrap = new ServerBootstrap();
			// reactor多线程模型，配置bossGroup和workGroup
			// bossGroup和workGroup使用spring容器管理
			serverBootstrap.group(getBossGroup(), getWorkerGroup()).channel(NioServerSocketChannel.class)
					.option(ChannelOption.SO_BACKLOG, 1024)
					.option(ChannelOption.SO_KEEPALIVE, true)//SO_KEEPALIVE 保持连接检测对方主机是否崩溃，避免（服务器）永远阻塞于TCP连接的输入
					.childHandler(getChannelInitializer());
			// 绑定端口，启动并监听
			Channel serverChannel = serverBootstrap.bind(sendCustomNettyConfig.getSocketAddress()).sync().channel();
			ALL_CHANNELS.add(serverChannel);
		} catch (Exception e) {
			LOG.error("TCP Server start error {}, going to shut down", e);
			getBossGroup().shutdownGracefully();
			getWorkerGroup().shutdownGracefully();
			super.stopServer();
			throw e;
		}
	}

	@Override
	public TransmissionProtocol getTransmissionProtocol() {
		return TRANSMISSION_PROTOCOL.TCP;
	}

	// 配置自己的initializer
	@Override
	public void setChannelInitializer(ChannelInitializer<? extends Channel> initializer) {
		this.sendCustomChannelInitializer = initializer;
		serverBootstrap.childHandler(initializer);
	}

	@Override
	public String toString() {
		return "CustomTCPServer [socketAddress=" + sendCustomNettyConfig.getSocketAddress() + ", portNumber="
				+ sendCustomNettyConfig.getPortNumber() + "]";
	}

}
